package com.cloud.common.rpc;

import lombok.Data;

import java.lang.reflect.Type;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;

/**
 * 响应
 *
 * @author fengwenjin
 */
@Data
public class ResponseFuture<T> implements Future {
	int sequence;
	Type returnType;
	T result;

	int timeout;
	long invalidTime;
	CountDownLatch latch = new CountDownLatch(1);

	public ResponseFuture(int sequence, int timeout, Type returnType) {
		this.sequence = sequence;
		this.timeout = timeout;
		this.invalidTime = System.currentTimeMillis() + timeout + 1000L;
		this.returnType = returnType;
	}

	@Override
	public boolean cancel(boolean mayInterruptIfRunning) {
		return false;
	}

	@Override
	public boolean isCancelled() {
		return false;
	}

	@Override
	public boolean isDone() {
		return latch.getCount() <= 0;
	}

	@Override
	public T get() throws InterruptedException {
		return get(timeout, TimeUnit.MILLISECONDS);
	}

	@Override
	public T get(long timeout, TimeUnit unit) throws InterruptedException {
		if (!isDone()) {
			try {
				latch.await(timeout, unit);
			} finally {
				ResponseFutureManager.remove(sequence);
			}
		}
		return result;
	}

	public void setResult(T result) {
		this.result = result;
		latch.countDown();
	}
}
